#ifndef _P2P_PROTO_H_
#define _P2P_PROTO_H_

#include "vpi.h"

#define P2P_PROTO_TYPE  0x8002
#define P2P_PROTO_NAME  "p2p"
#define P2P_PROTO_VER   "2.1.4"

extern const sproto_header * p2p_default_header;
//============================================================================
// P2P协议
/* protocol spec */
/** don't use because cmd is too decentralized,control by switch */
#define IS_P2P_DOWNCMD(cmd) (1) 
#define IS_P2P_UPCMD(cmd)   (1) 

#define P2P_TOP_1 0x40
#define P2P_TOP_2 0x21
#define P2P_END   0x23

// server --> device : down cmd
#define P2P_RE_LOGIN_DEV    0x80
#define P2P_CLIENT_CALL		0x81
#define P2P_HEART_TIME		0x82
#define P2P_YOUR_UDTADDR	0x83 // deprecated,removed
#define P2P_RE_HEART		0x84
#define P2P_CLI_CALL_AGAIN  0x89
#define P2P_RE_CLIADDR		0x8B
#define P2P_CLI_CALL_MAP	0x8D
#define P2P_SERVER_GETNAT	0x8F
#define P2P_SERVER_TURN		0xC1
// register server cmd
#define P2P_SERVER_LIST 	0xD3
#define P2P_SERVER_REG_OK   0x90
#define P2P_SERVER_REG_FAIL 0x96

// device --> server : up cmd
#define P2P_NEWDEV_LOGINE	0x04 // new device login
#define P2P_RES_TURN_SERVER 0x80000001 // res 0xC1 
#define P2P_SNDVIDEO_INFORM 0x02 

#define P2P_DEV_LOGINE		0x85
#define P2P_HOLE_DONE		0x86 // deprecated,removed
#define P2P_GET_UDTADDR		0x87
#define P2P_DEV_HEART		0x88
#define P2P_GET_UDTADDR_AGAIN 0x8A
#define P2P_MAP_UDT_PORT	0x8E
#define P2P_RE_SERVER_NAT	0x94
// register device cmd
#define P2P_QUERY_DOMAINS   0xD2
#define P2P_QUERY_REGISTE   0x01

// device --> client
#define P2P_DATA_OK			0x8C

#if 0
// server --> client
#define P2P_RESPONSE_LOGIN 0x90
#define P2P_SEND_DEVINFO   0x91
#define P2P_RESPONSE_STAT  0x92
#define P2P_SEND_NEWLINK   0x93
#define P2P_QUERY_PCNAT    0x95
#define P2P_RESPONSE_LIST  0xD5

// client --> server
#define P2P_PC_LOGIN  0x96
#define P2P_WATCH_DEV 0x97
#define P2P_WATCH_DEV_INVERSE 0x98
#define P2P_SEND_DATA_END 0x99
#define P2P_RE_PCNAT  0xD1
#define P2P_GET_DOMAINS 0xD4
#endif 

#if 0
#define P2P_SND_RTT         0xE0
#define P2P_RCV_RTT         0xE1
#endif

// login status
#define P2P_LOGIN_OK   0x0a
#define P2P_LOGIN_FAIL 0x0b

enum stun_net_type
{
	STUN_HOST_UNKNOWN = 0,
	STUN_UNKNOWN_ERR,
	STUN_OPENNAT,
	STUN_BLOCKED_UDP,
	STUN_FIREWALL,
	STUN_NAT_FC,
	STUN_NAT_RC,
	STUN_NAT_PC,
	sTUN_NAT_SN
};
enum stun_route_loop
{
	ROUTE_UNSUPPORT = 0,
	ROUTE_SUPPORT,
	ROUTE_UNKNOWN
};
//============================================================================
//down cmd
typedef struct ip_port_pairs
{
	char pc_ip[16];
	unsigned int pc_port;
	char dev_ip[16];
	unsigned int dev_port;
}sip_port_pairs;
typedef struct pc_ip_port
{
	char ip[16];
	unsigned int port;
}spc_ip_port;
typedef struct id_stun_domain
{
	char id[12];
	char domain[32];
}sid_stun_domain;
typedef struct domain_port
{
	char domain[32];
	unsigned int port;
}sdomain_port;
typedef struct dns_p2p_domain_list
{
	char dev_domain[32];
	sdomain_port dns_1;
	sdomain_port dns_2;
	sdomain_port p2p_1;
	sdomain_port p2p_2;
}sdomain_list;
typedef struct server_domain_list
{
	sdomain_port p2p;
	sdomain_port nat;
	char dev_domain[32];
	sdomain_port dns_1;
	sdomain_port dns_2;
	sdomain_port update;
}server_list;

typedef union p2p_down_content
{
	unsigned char login_status;
	sip_port_pairs client_info;
	unsigned short heart_sec;
	sip_port_pairs new_link_info;
	sip_port_pairs client_info_inverse;
	spc_ip_port    res_snd_ok_inverse;
	spc_ip_port    get_udp_map;
	sid_stun_domain get_network_nat;
	sdomain_list    res_domain_list;
	server_list		reg_server_list;
	unsigned char	reg_fail_dummy;
	spc_ip_port    get_turn_server;
}up2p_down_content;

// up cmd
struct login_p2p_info
{
	char id[12];
	char ip[16];
	unsigned int port;
	char version[16];
};
struct res_turn_server 
{
	char id[12];
	char ip[16];
	unsigned int port;
};
struct dev_id_code 
{
	char id[12];
	char code[16];
};
typedef union p2p_up_content
{
	struct login_p2p_info login;
	struct {
		char id[12];
		char version[16];
	} regist_domain_list;
	sip_port_pairs hole_done;
	sip_port_pairs get_udtaddr;
	struct {
		unsigned char flag;
		unsigned short heart_sec;
		char id[12];
	} heart_data;
	sip_port_pairs get_udtaddr_inverse;
	sip_port_pairs map_udt_port;
	struct stun_info
	{
		unsigned char net_type;
		unsigned char route_loop;
		char id[12];
	} re_server_nat;
	char dev_id[12];
	struct res_turn_server res_turn_server;
	struct dev_id_code send_video_inform;
}up2p_up_content;

typedef struct p2p_content
{
	up2p_down_content down_content;
	up2p_up_content   up_content;
}sp2p_content;

// 构建报文接口
int p2p_build_package(eproto_role role,sproto_msg *pmsg,unsigned char *sendbuff, int *len);

// 解析报文接口
int p2p_parse_package(eproto_role role,sproto_msg *pmsg,unsigned char *recvbuff, int len);

#endif

